package org.box.demos.multithreading.wgetmt;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.box.demos.multithreading.wgetmt.core.URL;
import org.box.metadata.cli.CommandLineParser;
import org.box.metadata.cli.MetaCommandLineParser;
import org.box.metadata.cli.annotation.Arguments;
import org.box.metadata.cli.annotation.CLIConfiguration;
import org.box.metadata.cli.annotation.Option;

/**
 * <a href="http://code.google.com/p/meta-cli/">meta-cli<a> oriented
 * application's configuration. Please visit <a
 * href="http://code.google.com/p/meta-cli/">meta-cli<a> for more information
 * 
 * @see MetaCommandLineParser
 * @see CommandLineParser
 * 
 * @author <a href="mailto:alexander.box@gmail.com">Alexander Korobka</a>
 * 
 */

@CLIConfiguration
public class Configuration {

	public static final String DEFAULT_THREAD_NUMBER = "10";
	public static final String DEFAULT_URL_LEVEL = "1";
	private static final String DEFAULT_OUTPUT_DIR = "./";
	
	@Option(description = "print this help.", 
			fullName = "help", 
			shortName = "h")
	private boolean help;

	@Option(description = "specify recursive download.", 
			fullName = "recursive", 
			shortName = "r")
	private boolean recursive;

	@Option(description = "maximum recursion depth (1 by default).", 
			fullName = "level", 
			shortName = "l", 
			hasArguments = true)
	String level = DEFAULT_URL_LEVEL;

	@Option(description = "threads number (10 by default).", 
			fullName = "threads", 
			shortName = "t", 
			hasArguments = true)
	String threads = DEFAULT_THREAD_NUMBER;
	
	@Option(description = "save files to PREFIX/...", 
			fullName = "directory-prefix", 
			shortName = "P", 
			hasArguments = true)
	String out = DEFAULT_OUTPUT_DIR;

	@Option(description = "re-point links on the local files. Uses for recursive mode only", 
			fullName = "convert-links", 
			shortName = "k")
	boolean convertLinks;
	
	@Option(description = "show skipped log", 
			fullName = "skip-log", 
			shortName = "sl")
	private boolean showSkipLog;

	@Option(description = "reg-exp pattern of accepted urls", 
			fullName = "accept", 
			shortName = "A",
			hasArguments = true)
	private String downloadPattern;
	private transient Pattern dp;

	@Option(description = "reg-exp pattern of rejected urls", 
			fullName = "reject", 
			shortName = "R",
			hasArguments = true)
	private String skipPattern;
	private transient Pattern sp;
	
	@Option(description = "storing URLs download state to Native Databese to resume download on next run", 
			fullName = "native-database", 
			shortName = "ndb",
			hasArguments = true)
	private String database;
	
	@Option(description = "a download size limit (megabytes) after reached that the new downloads will not be started", 
			fullName = "download-limit", 
			shortName = "dl",
			hasArguments = true)
	private String downladLimit;
	private transient int dl = -1;
	
	@Arguments(syntax = "url1, url2 ... \n Example: wget-mt -r -l2 -Pout http://www.apache.org/")
	private final String[] urls = new String[0];

	/**
	 * Do print help?
	 * 
	 * @return returns true, is --help or -h keys are specified by user
	 */
	public boolean isHelp() {
		return help;
	}

	/**
	 * Is recursive mode on?
	 * 
	 * @return returns true, if recursive mode is turns on
	 */
	public boolean isRecursive() {
		return recursive;
	}

	/**
	 * A maximum recursion depth (1 by default).
	 * 
	 * @return a number of max depth level
	 */
	public int getMaxLevel() {
		return Integer.parseInt(level);
	}

	/**
	 * A number of threads to process
	 * 
	 * @return the number of threads
	 */
	public int getThreads() {
		return Integer.parseInt(threads);
	}

	/**
	 * Returns a list of urls passed as parameters to the application
	 * 
	 * @return a list of urls
	 */
	public List<URL> getUrls() {
		List<URL> list = new ArrayList<URL>();
		for (String url: urls) {
			list.add(new URL(url));
		}
		return list;
	}

	/**
	 * Returns a directory for output
	 * 
	 * @return directory path as a string;
	 */
	public String getOutDir() {
		return out;
	}

	/**
	 * Convert links to point on the local files
	 * 
	 * @return true, if conversion is required
	 */
	public boolean convertLinks() {
		return convertLinks;
	}

	/**
	 * Show or not skipped files in the application's output log
	 * 
	 * @return true, if skip log have to be on
	 */
	public boolean showSkipLog() {
		return showSkipLog;
	}

	/**
	 * Regular expression of files to download
	 * 
	 * @return a string of reg. expression
	 */
	public Pattern getDownloadPattern() {
		if (dp == null && downloadPattern != null && !downloadPattern.trim().isEmpty()) {
			dp = Pattern.compile(downloadPattern, Pattern.CASE_INSENSITIVE & Pattern.MULTILINE);
		}
		return dp;
	}
	
	/**
	 * Regular expression of files to skip
	 * 
	 * @return a string of reg. expression
	 */
	public Pattern getSkipPattern() {
		if (sp == null && skipPattern != null && !skipPattern.trim().isEmpty()) {
			sp = Pattern.compile(skipPattern, Pattern.CASE_INSENSITIVE & Pattern.MULTILINE);
		}
		return sp;
	}
		
	public String getDatabaseName() {
		return database;
	}
	
	public int getDownladLimit() {
		if (downladLimit != null )
			dl = Integer.parseInt(downladLimit);
		
		return dl;
	}
}
